class LazyProperty(object):
    """
    实现惰性求值(访问时才计算，并将值缓存)
    第一次时，没有实例属性area，第二次时添加了实例属性area 且 实例属性要比 非数据描述符优先级更高
    """

    def __init__(self, fun):
        print("---LazyProperty init方法---")
        self.fun = fun

    def __get__(self, instance, owner):  # instance指向当前操作对象(a)  ，owner指向 当前对象的 类(Circle)
        print("---LazyProperty __get__---")
        # if instance is None:
        #     return self
        value = self.fun(instance)  # 相当于 area()  # 如果我们是    对象.area()
        setattr(instance, self.fun.__name__, value)  # 相当于给某个对象添加了一个属性，且赋值；a.area = 50.24
        return value


class Circle(object):
    pi = 3.14

    def __init__(self, radius):
        print("类Circle的init方法执行....")
        self.radius = radius

    @LazyProperty  # 等价于 area = LazyProperty(area)
    def area(self):
        print('Computing area')
        return self.pi * self.radius ** 2


a = Circle(4)
print("---1--")

print(a.area)  # 正常来说，如果不用描述符，调用 area方法的方式是  a.area()，因为area已经是一个描述符，所以直接a.area
print("---2--")

print(a.area)  # 调用的是 实例属性area的值？还是 描述符area的值呢？
# print("---3--")
